/*!
    \file    gd32e23x_it.c
    \brief   interrupt service routines
    
    \version 2019-02-19, V1.0.0, firmware for GD32E23x
    \version 2020-12-12, V1.1.0, firmware for GD32E23x
*/

#include "gd32e23x_it.h"
#include "main.h"
#include "uart_peripheral.h"
#include "delay.h"
#include "led.h"

#ifndef USE_FREERTOS
	#define USE_FREERTOS 1
#endif

/*!
    \brief      this function handles NMI exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void NMI_Handler(void)
{
}

/*!
    \brief      this function handles HardFault exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
void HardFault_Handler(void)
{
    while(1){
		LEDToggle();
		delayXms(125);
    }
}

/*!
    \brief      this function handles SVC exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
#if !USE_FREERTOS
void SVC_Handler(void)
{
}
#endif

/*!
    \brief      this function handles PendSV exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
#if !USE_FREERTOS
void PendSV_Handler(void)
{
}
#endif

/*!
    \brief      this function handles SysTick exception
    \param[in]  none
    \param[out] none
    \retval     none
*/
#if !USE_FREERTOS
void SysTick_Handler(void)
{
}
#endif

void USART0_IRQHandler(void)
{
#if USE_FREERTOS
	uint32_t ulReturn = taskENTER_CRITICAL_FROM_ISR();
#endif
	
	UartInterruptHandle(UART_COM0);

#if USE_FREERTOS
	taskEXIT_CRITICAL_FROM_ISR(ulReturn);
#endif
}

void USART1_IRQHandler(void)
{
#if USE_FREERTOS
	uint32_t ulReturn = taskENTER_CRITICAL_FROM_ISR();
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
#endif
	
	UartInterruptHandle(UART_COM1);

#if USE_FREERTOS
	xEventGroupSetBitsFromISR(APPEventGroup, APP_EVENT_UART0_GET, &xHigherPriorityTaskWoken);
	
	taskEXIT_CRITICAL_FROM_ISR(ulReturn);
#else
	APP_EVENT_SET(APP_EVENT_UART0_GET);
#endif
}

void DMA_Channel1_2_IRQHandler(void)
{
#if USE_FREERTOS
	uint32_t ulReturn = taskENTER_CRITICAL_FROM_ISR();
#endif
	
	if (dma_interrupt_flag_get(DMA_CH1, DMA_INT_FLAG_FTF) == SET) {
		UartDMAInterruptHandle(UART_COM0);
	}
	
#if USE_FREERTOS
	taskEXIT_CRITICAL_FROM_ISR(ulReturn);
#endif
}

void DMA_Channel3_4_IRQHandler(void)
{
#if USE_FREERTOS
	uint32_t ulReturn = taskENTER_CRITICAL_FROM_ISR();
#endif
	
	if (dma_interrupt_flag_get(DMA_CH3, DMA_INT_FLAG_FTF) == SET) {
		UartDMAInterruptHandle(UART_COM1);
	}

#if USE_FREERTOS
	taskEXIT_CRITICAL_FROM_ISR(ulReturn);
#endif
}

void TIMER16_IRQHandler(void)
{
#if USE_FREERTOS
	uint32_t ulReturn = taskENTER_CRITICAL_FROM_ISR();
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
#endif
	
	if (timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_UP) == SET) {
		timer_interrupt_flag_clear(TIMER16, TIMER_INT_FLAG_UP);
	}

#if USE_FREERTOS
	xEventGroupSetBitsFromISR(APPEventGroup, APP_EVENT_FRAME_FLUSE, &xHigherPriorityTaskWoken);
	
	taskEXIT_CRITICAL_FROM_ISR(ulReturn);
#else
	APP_EVENT_SET(APP_EVENT_FRAME_FLUSE);
#endif
}

void EXTI0_1_IRQHandler(void)
{
#if USE_FREERTOS
	uint32_t ulReturn = taskENTER_CRITICAL_FROM_ISR();
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
#endif
	
	if (exti_flag_get(EXTI_1) == SET) {
		exti_flag_clear(EXTI_1);
	#if USE_FREERTOS
		xEventGroupSetBitsFromISR(APPEventGroup, APP_EVENT_EXTI_1, &xHigherPriorityTaskWoken);
	#else
		APP_EVENT_SET(APP_EVENT_EXTI_1);
	#endif
	}
	
#if USE_FREERTOS
	taskEXIT_CRITICAL_FROM_ISR(ulReturn);
#endif
}
